package l.com.qqdemo;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2017/12/21.
 */

public class DragLayout extends ViewGroup {
    View redView;
    View blueView;
    ViewDragHelper dragHelper;
    DragCallback callback;

    public DragLayout(Context context) {
        super(context);
        init();
    }


    public DragLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        callback = new DragCallback();

        dragHelper = ViewDragHelper.create(this, callback);
    }

    /**
     * 当DragLayout的xml布局的结束标签被读取完成会执行,此时就知道几个子view  fixme
     * 一般用来初始化子view的引用
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        redView = getChildAt(0);
        blueView = getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //  float size = getResources().getDimension(R.dimen.width);
        int measureSpec = MeasureSpec.makeMeasureSpec(redView.getLayoutParams().width, MeasureSpec.EXACTLY);
        redView.measure(measureSpec, measureSpec);
        blueView.measure(measureSpec, measureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = getPaddingLeft();
        int top = getPaddingTop();

        redView.layout(left, top, left + redView.getMeasuredWidth(), top + redView.getMeasuredHeight());
        blueView.layout(left, redView.getBottom(), blueView.getMeasuredWidth(), redView.getBottom() + blueView.getMeasuredHeight());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //把触摸事件交给Helper来解析处理
        dragHelper.processTouchEvent(event);
        return true;
    }

    /**
     * 拦截方法  fixme
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result = dragHelper.shouldInterceptTouchEvent(ev);
        return result;
    }


    class DragCallback extends ViewDragHelper.Callback {
        /**
         * 用于判断是否捕获当前child的触摸事件
         *
         * @param child     当前触摸的子view
         * @param pointerId
         * @return
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            // TODO: 2017/12/22 step1 确定捕获的对象
            // TODO: 2017/12/22 多点触摸属性
            return child == blueView || child == redView;
        }

        /**
         * 当view被开始捕获和解析的回调
         *
         * @param capturedChild
         * @param activePointerId
         */
        @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            super.onViewCaptured(capturedChild, activePointerId);
            Log.e("执行", "onViewCaptured: 开始捕获");
            // TODO: 2017/12/22 step2 监听对象事件的开始
        }

        /**
         * 控制child在水平方向的移动
         *
         * @param child
         * @param left  ViewDragHelper认为你想让当前child的left改变值,left = child.getLeft() + dx
         * @param dx    本次child水平方向移动的距离
         * @return 你想让child的left变成的值
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            // TODO: 2017/12/22 step3 return left 对象可以左右滑动 修改left的值确定移动边界  left = child.getLeft() + dx
            // todo return left - dx 左右不能移动
            Log.e("执行", "clampViewPositionHorizontal: left--" + left + "dx--" + dx);
            if (left < 0) {
                left = 0;
            } else if (left > getMeasuredWidth() - child.getMeasuredWidth()) {
                left = getMeasuredWidth() - child.getMeasuredWidth();
            }
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            // TODO: 2017/12/22 step4 return top child对象可以上下滑动
            if (top < 0) {
                top = 0;
            } else if (top > getMeasuredHeight() - child.getMeasuredHeight()) {
                top = getMeasuredHeight() - child.getMeasuredHeight();
            }
            return top;
        }

        /**
         *
         *
         * @param child
         * @return
         */
        @Override
        public int getViewHorizontalDragRange(View child) {
            // TODO: 获取view水平方向的拖拽范围,但是目前不能限制边界,返回的值目前用在手指抬起的时候view缓慢移动的动画事件的计算上面
            // todo 最好不要返回0

         //   return super.getViewHorizontalDragRange(child);
            return getMeasuredWidth() - child.getMeasuredWidth();
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            //  return super.getViewVerticalDragRange(child);
            return getMeasuredHeight() - child.getMeasuredHeight();
        }

        /**
         todo  当child位置改变的时候执行,一般用来做其他view的伴随移动
         * @param changedView  位置改变的child
         * @param left  child当前最新的left
         * @param top
         * @param dx  本次水平移动的距离
         * @param dy
         */
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            // TODO: 2017/12/22 step5 伴随移动
            if (changedView == blueView) {
                // FIXME: 2017/12/22 红色伴随蓝色移动
                redView.layout(redView.getLeft() + dx,redView.getTop() + dy,
                        redView.getRight() + dx,redView.getBottom() + dy );

            } else if (changedView == redView) {
                // FIXME: 2017/12/22 蓝色色伴随红色移动


            }
            // TODO: 2017/12/22 step7 蓝色view移动时,红色做伴随特效动画
            //1.计算view移动的百分比
            float fraction = changedView.getLeft()*1f/(getMeasuredWidth()- changedView.getMeasuredWidth());
            Log.e("执行", "onViewPositionChanged: fraction---" + fraction);
            //2.执行一系列的伴随动画
            executeAnim(fraction);
            
        }

        /**
         todo  step6 手指抬起时执行的方法 用来做抬起后的移动动画
         * @param releasedChild  当前抬起的view
         * @param xvel x方向移动的速度  正:向右移动
         * @param yvel
         */
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
          int centerLeft =  (getMeasuredWidth()- releasedChild.getMeasuredWidth())/2;
          if (releasedChild.getLeft() <centerLeft) {
              //抬起,向左移动  step1 关键在左边坐标
              dragHelper.smoothSlideViewTo(releasedChild,0,releasedChild.getTop());
              ViewCompat.postInvalidateOnAnimation(DragLayout.this);
          } else {
              //向右移动  step1 关键在左边坐标
              dragHelper.smoothSlideViewTo(releasedChild,getMeasuredWidth() - releasedChild.getMeasuredWidth(),releasedChild.getTop());
              ViewCompat.postInvalidateOnAnimation(DragLayout.this);
          }


        }
        @Override
        public void onViewDragStateChanged(int state) {
            super.onViewDragStateChanged(state);
        }

    }

    /**
     执行动画
     * @param fraction
     */
    private void executeAnim(float fraction) {
        //todo 缺少颜色渐变的ColorUtil
        ObjectAnimator moveIn = ObjectAnimator.ofFloat(redView, "translationX", -500f*fraction, 0f);
        ObjectAnimator rotate = ObjectAnimator.ofFloat(redView, "rotation", 0f, 360f*fraction);
        ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(redView, "alpha", 0.2f + 0.8f*fraction, 0.2f, 0.2f + 0.8f*fraction);
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(rotate).with(fadeInOut).after(moveIn);
     //   animSet.setDuration(5000);
        animSet.start();
    }

    @Override

    //step 2  滚动代码
    public void computeScroll() {
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(DragLayout.this);
        }
    }
}

